package com.icarus.view;


import com.icarus.entity.*;
import com.icarus.util.DataUtil;
import javazoom.jl.player.Player;

import javax.sound.midi.Soundbank;
import javax.swing.*;


import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * 游戏主界面
 */
public class MainView extends JPanel {

    //游戏窗口大小
    public static final int WIDTH = 512;
    public static final int HEIGHT = 650;

    //当前屏幕大小宽高度
    public static final int SCREEN_WIDTH = (int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth());
    public static final int SCREEN_HEIGHT = (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight());


    //提供对外访问方法
    public static MainView getInstance() {
        return instance;
    }

    //初始化英雄角色
    public static final Hero hero = new Hero();


    //初始化敌方角色集合 线程安全的集合
    public static final List<Enemy> enemys = Collections.synchronizedList(new ArrayList<>());

    //初始化敌方角色的数量
    private static final int enemyNum = 3;

    //创建游戏主界面对象
    private static final MainView instance = new MainView();

    //场景
    private Scene scene;

    //初始化爆炸效果集合 线程安全的集合
    private static final List<Bomb> bombs = Collections.synchronizedList(new ArrayList<>());

    //构造器私有化
    private MainView() {
        //初始化场景
        scene = new Scene();
        scene.setLevel(1);  //第一关场景
        scene.setX(0);
        scene.setY(0);

        //随机场景
        int randSceneNum = DataUtil.getAssignRangeRandom(1,4);
        scene.setIcon(new ImageIcon("images/bg/bg"+randSceneNum+".jpg"));

        //启动场景
        new Thread(scene).start();

    }


    //初始化窗口
    private void init() {

        JFrame jFrame = new JFrame();
        //设置标题
        jFrame.setTitle("伊卡洛斯");
        //设置窗口大小
        jFrame.setSize(WIDTH, HEIGHT);
        //设置位置居中显示
        jFrame.setLocation(SCREEN_WIDTH / 2 - WIDTH / 2, SCREEN_HEIGHT / 2 - HEIGHT / 2);
        //关闭退出
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置标题栏icon
        jFrame.setIconImage(new ImageIcon("images/hero/hero_b_02.png").getImage());
        //窗口大小固定
        jFrame.setResizable(false);
        //布局管理器null
        jFrame.setLayout(null);
        //设置可见性
        jFrame.setVisible(true);
        //Jpanel设置大小和位置
        this.setBounds(0, 0, WIDTH, HEIGHT);

        jFrame.add(this);

        //添加键盘监听
        jFrame.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {

            }

            //键盘按下
            @Override
            public void keyPressed(KeyEvent e) {
                //控制wsad键盘
                if(hero.isAlive()) {
                    switch (e.getKeyCode()) {
                        case 87:
                            //W
                            hero.moveUp();
                            break;
                        case 83:
                            //S
                            hero.moveDown();
                            break;
                        case 65:
                            //A
                            hero.moveLeft();
                            break;
                        case 68:
                            //D
                            hero.moveRight();
                            break;
                        case 74:
                            //J 攻击
                            hero.attack();
                            break;
                    }
                    //刷新界面
                    instance.repaint();
                }
            }
            @Override
            public void keyReleased(KeyEvent e) {

            }
        });

    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //添加背景图片
        this.setGameBg(g);
        //画出我方英雄
        this.setHero(g);
        //画出我方英雄射击子弹
        this.setHeroBullet(g);
        //画出敌人飞机
        this.setEnemys(g);
        //敌方飞机子弹
        this.setEnemysBullet(g);

        //画出爆炸效果
        this.showBomb(g);
    }


    //添加背景图片
    private void setGameBg(Graphics g) {
        //背景图拼接
        g.drawImage(scene.getIcon().getImage(), scene.getX(), scene.getY() + (-HEIGHT), WIDTH, HEIGHT, this);
        g.drawImage(scene.getIcon().getImage(), scene.getX(), scene.getY(), WIDTH, HEIGHT, this);
    }

    //画出我方英雄
    private void setHero(Graphics g) {

        if(hero.isAlive()) {
            g.drawImage(hero.getIcon().getImage(), hero.getX(), hero.getY(), hero.getIcon().getIconWidth(), hero.getIcon().getIconHeight(), this);
        }

    }

    //画出我方英雄射击子弹
    private void setHeroBullet(Graphics g) {
        //获取英雄子弹
        List<Bullet> bullets = hero.getBullets();
        for (Bullet bullet : bullets) {
            if(bullet.getStatus()==0) {
                g.drawImage(bullet.getIcon().getImage(), bullet.getX(), bullet.getY(), bullet.getIcon().getIconWidth(), bullet.getIcon().getIconHeight(), this);
            }

        }
    }


    //画出敌方的子弹
    private void setEnemysBullet(Graphics g) {
        for(Enemy enemy:enemys) {
            List<Bullet> bullets = enemy.getBullets();
            for (Bullet bullet : bullets) {
                if(bullet.getStatus()==0) {
                    g.drawImage(bullet.getIcon().getImage(), bullet.getX(), bullet.getY(), bullet.getIcon().getIconWidth(), bullet.getIcon().getIconHeight(), this);
                }
            }

        }

    }


    //画出敌人飞机
    private void setEnemys(Graphics g) {
        //画出敌人飞机
        for (Enemy enemy : enemys) {
            if(enemy.isAlive()) {
                g.drawImage(enemy.getIcon().getImage(), enemy.getX(), enemy.getY(), enemy.getIcon().getIconWidth(), enemy.getIcon().getIconHeight(), this);
            }
        }

    }


    //画出爆炸效果
    private void showBomb(Graphics g) {
        for(Bomb bomb:bombs) {
            if(bomb.getStauts()==0) {
                g.drawImage(bomb.getIcon().getImage(), bomb.getX(), bomb.getY(), bomb.getIcon().getIconWidth(), bomb.getIcon().getIconHeight(), this);
                bomb.boom();
            }
        }

    }



    //移除掉爆炸效果
    private void removeDieBomb() {
        Iterator<Bomb> iterator = bombs.iterator();
        while (iterator.hasNext()) {
            Bomb bomb = iterator.next();
            if(bomb.getStauts()==1) {
                iterator.remove();
            }
        }

    }



    //移除已经用掉的子弹
    private void removeUsedBullets() {

        //移除英雄的用掉的子弹
        List<Bullet> bullets = hero.getBullets();
        Iterator<Bullet> iterator = bullets.iterator();
        while (iterator.hasNext()) {
            Bullet bullet = iterator.next();
            if (bullet.getStatus() == 1) {
                iterator.remove();
            }
        }


        //移除敌人用掉的子弹
        for(Enemy enemy:enemys) {
            bullets = enemy.getBullets();
            iterator = bullets.iterator();
            while (iterator.hasNext()) {
                Bullet bullet = iterator.next();
                if (bullet.getStatus() == 1) {
                    iterator.remove();
                }
            }

        }
    }



    //按随机数判断敌人是否攻击
    private void judgeEnemyIsAttack() {

        for(Enemy enemy:enemys) {
            //根据1-100随机数大于等于多少的情况下 敌人发动攻击

            //敌人是否活着
            if(enemy.isAlive()) {
                int randAttack = DataUtil.getAssignRangeRandom(1,100);

                //小兵 随机数大于95时候发动攻击
                if(enemy.getType()==0) {
                    if(randAttack>95) {
                        enemy.attack();
                    }
                } else {
                    //boss 随机数大于90时候发动攻击
                    if(randAttack>90) {
                        enemy.attack();
                    }
                }

            }

        }

    }



    //播放背景音乐
    private void playBgMusic() {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            File file = new File("music/pegasusforever.mp3");
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            Player player = new Player(bis);
            player.play();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    //判断敌人子弹是否打中了我
    private void hitWhetherMe() {

        for(Enemy enemy:enemys) {

            List<Bullet> bullets = enemy.getBullets();

            for(Bullet bullet:bullets) {

                //如果英雄还活着
                if(hero.isAlive()) {
                    //获取子弹的横纵坐标
                    int x = bullet.getX();
                    int y = bullet.getY();

                    //英雄坐标
                    int heroX = hero.getX();
                    int heroY = hero.getY();

                    int width = hero.getIcon().getIconWidth();
                    int height = hero.getIcon().getIconHeight();


                    if(y>=heroY&&y<=(heroY+height)&&x>=heroX&&x<=(heroX+width)) {
                        // 击中后
                        //敌方方子弹消亡
                        bullet.setStatus(1);
                        //打中的话生命值减一点
                        hero.setHp(hero.getHp()-1);

                        //生命值为0的话则拜拜了
                        if(hero.getHp()==0) {
                            //敌人状态更改为死亡
                            hero.setAlive(false);

                            //跳出爆炸效果
                            Bomb bomb = new Bomb();
                            bomb.setX(hero.getX());
                            bomb.setY(hero.getY());
                            bomb.setIcon(hero.getIcon());
                            bombs.add(bomb);
                        }

                        break;

                    }

                }

            }

        }

    }



    //我方战机是否击中敌人
    private void hitWhetherEnemy() {

        List<Bullet> bullets = hero.getBullets();

        for(Bullet bullet:bullets) {

            //获取子弹的横纵坐标
            int x = bullet.getX();
            int y = bullet.getY();


            for(Enemy enemy:enemys) {

                if(enemy.isAlive()) {
                    //获取出敌人的坐标和 宽度长度
                    int enemyY = enemy.getY();
                    int enemyX = enemy.getX();
                    int width = enemy.getIcon().getIconWidth();
                    int height = enemy.getIcon().getIconHeight();

                    if(y>=enemyY&&y<=(enemyY+height)&&x>=enemyX&&x<=(enemyX+width)) {
                        //击中后
                        //我方子弹消亡
                        bullet.setStatus(1);


                        //打中的话生命值减一点
                        enemy.setHp(enemy.getHp()-1);

                        //生命值为0的话则拜拜了

                        if(enemy.getHp()==0) {
                            //敌人状态更改为死亡
                            enemy.setAlive(false);

                            //敌人拜拜 跳出爆炸效果
                            Bomb bomb = new Bomb();
                            bomb.setX(enemy.getX());
                            bomb.setY(enemy.getY());
                            bomb.setIcon(enemy.getIcon());
                            bombs.add(bomb);
                        }

                        //跳出循环
                        break;
                    }
                }

            }
        }
    }




    //自动添加敌人飞机
    private void autoAddEnemys() {
        int dieCount = 0;
        //获取已死亡敌人数量
        for(Enemy enemy:enemys) {
            if(!enemy.isAlive()) {
                dieCount++;
            }

        }

        //都死了的话可以加飞机
        if(dieCount==enemys.size()&&enemys.size()<enemyNum) {

            Enemy enemy = new Enemy();
            //敌人飞机是否还活着
            enemy.setAlive(true);
            enemy.setIcon(new ImageIcon("images/enemy/enemy.png"));
            enemy.setHp(1); //小兵1点生命
            enemy.setType(0);   //类型为小兵
            enemy.setSpeed(10); //速度为默认10
            enemy.setX(DataUtil.getAssignRangeRandom(0, WIDTH - enemy.getIcon().getIconWidth()));
            enemy.setY(0-enemy.getIcon().getIconHeight());
            //设置弹药库
            List<Bullet> bullets = new ArrayList<>();
            enemy.setBullets(bullets);

            enemys.add(enemy);

            Thread thread = new Thread(enemy);
            thread.start();    //开启线程 让敌方飞机自己运行

        }


        //加boss
        if(dieCount==enemys.size()&&enemys.size()==enemyNum) {

            boolean flag = false;
            for(Enemy enemy:enemys) {

                if(enemy.getType()==1) {
                    flag = true;
                    //已经有boss了
                }

            }

            //没有boss添加一个boss
            if(!flag) {

                Enemy enemy = new Enemy();
                //敌人飞机是否还活着
                enemy.setAlive(true);
                enemy.setIcon(new ImageIcon("images/enemy/boss.png"));
                enemy.setType(1);   //类型为小兵
                enemy.setHp(30);    //30点生命
                enemy.setSpeed(15); //速度为默认10
                enemy.setX(DataUtil.getAssignRangeRandom(0, WIDTH - enemy.getIcon().getIconWidth()));
                enemy.setY(0-enemy.getIcon().getIconHeight());
                //设置弹药库
                List<Bullet> bullets = new ArrayList<>();
                enemy.setBullets(bullets);

                enemys.add(enemy);

                Thread thread = new Thread(enemy);
                thread.start();    //开启线程 让敌方飞机自己运行
            }

        }


    }



    /**
     * 启动
     */
    public void launch() {
        //初始化游戏
        this.init();
        //开启线程 每100毫秒刷新界面
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        //敌人发动攻击
                        judgeEnemyIsAttack();
                        //我方英雄是否击中敌人
                        hitWhetherEnemy();

                        //敌人是否击中了我
                        hitWhetherMe();
                        //移除用掉的子弹
                        removeUsedBullets();
                        //移除爆炸里面的集合
                        removeDieBomb();
                        //自动添加敌人飞机
                        autoAddEnemys();
                        //刷新画布
                        instance.repaint();
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


        //游戏开始播放背景音乐
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    try {
                        playBgMusic();
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }.start();
    }

}
